#include <gtest/gtest.h>


typedef int sc_time;
#include "sc_noti_log.h"
using namespace sc_core;

int main(int argc, char **argv) {
	::testing::InitGoogleTest(&argc, argv);
	::testing::FLAGS_gtest_death_test_style = "threadsafe";
	return RUN_ALL_TESTS();
}

TEST(sc_noti_log, DefaultCons){
	sc_noti_log n;
	EXPECT_FALSE(n.has_immediate());
	EXPECT_FALSE(n.has_delta());
	EXPECT_FALSE(n.has_timed());
	EXPECT_DEATH(n.time(),".*Assertion `m_pending_type == TIMED' failed.*");
}



TEST(sc_noti_log,ImmediateOnly){
	sc_noti_log n;
	n.immediate();
	EXPECT_TRUE(n.has_immediate());
	EXPECT_FALSE(n.has_delta());
	EXPECT_FALSE(n.has_timed());
	
	n.immediate();
	n.immediate();
	EXPECT_TRUE(n.has_immediate());
	EXPECT_FALSE(n.has_delta());
	EXPECT_FALSE(n.has_timed());

	n.reset_immediate();
	EXPECT_FALSE(n.has_immediate());
	EXPECT_FALSE(n.has_delta());
	EXPECT_FALSE(n.has_timed());
}

TEST(sc_noti_log,DeltaOnly){
	sc_noti_log n;
	n.delta();
	EXPECT_FALSE(n.has_immediate());
	EXPECT_TRUE(n.has_delta());
	EXPECT_FALSE(n.has_timed());
	
	n.delta();
	n.delta();
	EXPECT_FALSE(n.has_immediate());
	EXPECT_TRUE(n.has_delta());
	EXPECT_FALSE(n.has_timed());

	n.reset_delta();
	EXPECT_FALSE(n.has_immediate());
	EXPECT_FALSE(n.has_delta());
	EXPECT_FALSE(n.has_timed());
}



TEST(sc_noti_log,TimedOnly){
	sc_noti_log n;
	sc_time t10=10;
	sc_time t2=2;
	sc_time t3=3;

	n.timed(t10);
	EXPECT_FALSE(n.has_immediate());
	EXPECT_FALSE(n.has_delta());
	EXPECT_TRUE(n.has_timed());
	EXPECT_EQ(n.time(),t10);
	EXPECT_NE(n.time(),t2);
	
	n.timed(t2);
	EXPECT_EQ(n.time(),t2);
	n.timed(t3);
	EXPECT_EQ(n.time(),t2);
	n.timed(t3);
	EXPECT_EQ(n.time(),t2);
	EXPECT_FALSE(n.has_immediate());
	EXPECT_FALSE(n.has_delta());
	EXPECT_TRUE(n.has_timed());

	n.timed(sc_time(1));
	EXPECT_EQ(n.time(),1);

	n.reset_timed();
	EXPECT_FALSE(n.has_immediate());
	EXPECT_FALSE(n.has_delta());
	EXPECT_FALSE(n.has_timed());
	EXPECT_DEATH(n.time(),".*Assertion `m_pending_type == TIMED' failed.*");
}

TEST(sc_noti_log,ImmediateAfterDelta){
	sc_noti_log n;
	
	n.delta();
	n.immediate();
	EXPECT_TRUE(n.has_immediate());
	EXPECT_FALSE(n.has_delta());
}


TEST(sc_noti_log,DeltaAfterImmediate){
	sc_noti_log n;
	
	n.immediate();
	n.delta();
	EXPECT_TRUE(n.has_immediate());
	EXPECT_TRUE(n.has_delta());
}

TEST(sc_noti_log,TimedAfterImmediate){
	sc_noti_log n;
	
	n.immediate();
	n.timed(sc_time(1));
	EXPECT_TRUE(n.has_immediate());
	EXPECT_TRUE(n.has_timed());
}

TEST(sc_noti_log,ImmediateAfterTimed){
	sc_noti_log n;
	
	n.timed(sc_time(1));
	n.immediate();
	EXPECT_TRUE(n.has_immediate());
	EXPECT_FALSE(n.has_timed());
}

TEST(sc_noti_log,TimedAfterDelta){
	sc_noti_log n;
	
	n.delta();
	n.timed(sc_time(1));
	EXPECT_TRUE(n.has_delta());
	EXPECT_FALSE(n.has_timed());
}


TEST(sc_noti_log,DeltaAfterTimed){
	sc_noti_log n;
	
	n.timed(sc_time(1));
	n.delta();
	EXPECT_TRUE(n.has_delta());
	EXPECT_FALSE(n.has_timed());
}


TEST(sc_noti_log,CancelDeltaOrTimed){
	sc_noti_log n;

	n.delta();
	n.cancel();
	EXPECT_FALSE(n.has_delta());
	n.timed(sc_time(1));
	EXPECT_TRUE(n.has_timed());
	n.cancel();
	EXPECT_FALSE(n.has_timed());
	n.timed(sc_time(2));
	EXPECT_EQ(n.time(),2);	
}



TEST(sc_noti_log,CancelImmediate){
	sc_noti_log n;

	n.immediate();
	n.cancel();
	EXPECT_TRUE(n.has_immediate());
}



